package br.com.iswe.core.persistence;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class PersistenceUtil {
	public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory";
	
	
	
	public static void executeInSessionContect(BeanFactory beanFactory, PersistenceUtilCallBack persistenceUtilCallBack) {
		String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME;
		executeInSessionContect(beanFactory, sessionFactoryBeanName, persistenceUtilCallBack);
	}

	
	public static void executeInSessionContect(BeanFactory beanFactory, String sessionFactoryBeanName, PersistenceUtilCallBack callBack) {
		SessionFactory sessionFactory = lookupSessionFactory(beanFactory, sessionFactoryBeanName);
		boolean participate = false;


		// single session mode
		if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
			// Do not modify the Session: just set the participate flag.
			participate = true;
		}
		else {
			//logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
			Session session = getSession(sessionFactory);
			TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
		}
		

		try {
			callBack.execute();
		}

		finally {
			if (!participate) {
				// single session mode
				SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
				//logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
				SessionFactoryUtils.closeSession(sessionHolder.getSession());
			}
		}
	}

	protected static Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
		Session session = SessionFactoryUtils.getSession(sessionFactory, true);
		//FlushMode flushMode = getFlushMode();
		//if (flushMode != null) {
		//	session.setFlushMode(flushMode);
		//}
		return session;
	}

	private static SessionFactory lookupSessionFactory(BeanFactory beanFactory, String sessionFactoryBeanName) {
		return (SessionFactory) beanFactory.getBean(sessionFactoryBeanName, SessionFactory.class);
	}

	
	
	
}
